<?php

declare(strict_types=1);

namespace App\Command;

use Hyperf\Command\Command as HyperfCommand;
use Hyperf\Command\Annotation\Command;
use Hyperf\DbConnection\Db;
use Psr\Container\ContainerInterface;

/**
 * @Command
 */
#[Command]
class SyncEra extends HyperfCommand
{
    /**
     * @var ContainerInterface
     */
    protected $container;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;

        parent::__construct('era_sync_test_to_prod');
    }

    public function configure()
    {
        parent::configure();
        $this->setDescription('era测试环境同步到生产环境数据');
    }

    public function handle()
    {
        // 先同步org，建立映射关系
        $orgIdMap = $this->syncOrg();

        $this->line('正在同步全表数据...');
        //全表同步
        $fullTables = [
            'gms_category',
            'gms_goods',
            'gms_goods_pack',
            'gms_goods_pack_sku',
            'gms_goods_sku',

            'keyword',
            'keyword_goods',
            'keyword_org',

            'wms_warehouse',
        ];
        foreach ($fullTables as $table) {
            $this->syncFullTable($table, $orgIdMap);
            $this->line('同步'.$table.'完成');
        }
    }


    // 全表同步
    public function syncFullTable($table, $orgIdMap = []) {
        try {
            // 先清空目标表
            Db::connection('era-prod')->table($table)->truncate();
            
            // 分批同步数据
            Db::connection('era-test')->table($table)
                ->orderBy('id')
                ->chunk(1000, function ($data) use ($table, $orgIdMap) {
                    $records = [];
                    foreach ($data as $row) {
                        $record = (array)$row;
                        //已删除数据忽略
                        if (isset($record['status']) && $record['status'] == 255) {
                            continue;
                        }
                        // 如果是gms_goods表且存在po_org字段，使用新的org ID
                        if ($table === 'gms_goods') {
                            $record['po_org'] = $orgIdMap[$record['po_org']] ?? 0;
                        }
                        
                        $records[] = $record;
                    }
                    
                    if (!empty($records)) {
                        Db::connection('era-prod')->table($table)->insert($records);
                    }
                });
            
            return true;
        } catch (\Exception $e) {
            throw new \RuntimeException("同步表 {$table} 失败: " . $e->getMessage());
        }
    }

    // 同步org数据
    public function syncOrg() {
        try {
            $this->line('正在同步org[5、6]数据...');
            // 1. 同步指定ID的org
            $orgs = Db::connection('era-test')->table('org')->whereIn('id', [5, 6])->get()->toArray();
            foreach ($orgs as $k => $org) {
                $orgs[$k] = (array)$org;
            }
            
            Db::connection('era-prod')->table('org')->insert($orgs);
            $this->line('正在同步供应商及其关联数据...');

            // 2. 同步供应商及其关联数据
            $suppliers = Db::connection('era-test')->table('org')
                ->where('type', 2)
                ->where('status', '<', 255)
                ->get();

            // 用于保存新旧ID映射关系
            $orgIdMap = [];
            $userIdMap = [];

            // 2.1 同步供应商
            foreach ($suppliers as $supplier) {
                $this->line('正在同步供应商'.$supplier->id.'及其关联数据...');
                $supplierData = (array)$supplier;
                $oldOrgId = $supplierData['id'];
                unset($supplierData['id']);
                
                // 插入供应商并获取新ID
                $newOrgId = Db::connection('era-prod')->table('org')->insertGetId($supplierData);
                $orgIdMap[$oldOrgId] = $newOrgId;

                // 2.2 查找并同步该供应商的联系人
                $teamMembers = Db::connection('era-test')
                    ->table('team')
                    ->where('org', $oldOrgId)
                    ->get();

                foreach ($teamMembers as $member) {
                    // 获取用户信息
                    $user = Db::connection('era-test')
                        ->table('user')
                        ->where('uid', $member->uid)
                        ->first();

                    if ($user) {
                        $this->line('正在同步供应商'.$supplier->id.'的联系人'.$user->uid.'及其关联数据...');
                        $userData = (array)$user;
                        $oldUserId = $userData['uid'];

                        // 检查用户是否已经同步过
                        if (!isset($userIdMap[$oldUserId])) {
                            unset($userData['uid']);
                            // 插入用户并保存新ID映射
                            $newUserId = Db::connection('era-prod')->table('user')->insertGetId($userData);
                            $userIdMap[$oldUserId] = $newUserId;
                        }

                        // 2.3 创建新的team关联
                        $teamData = (array)$member;
                        $teamData['uid'] = $userIdMap[$oldUserId];
                        $teamData['org'] = $orgIdMap[$oldOrgId];

                        Db::connection('era-prod')->table('team')->insert($teamData);
                    }
                }
            }
            $this->line('同步供应商及关联数据完成');
        
            return $orgIdMap;  // 返回org ID的映射关系
        } catch (\Exception $e) {
            throw new \RuntimeException("同步供应商及关联数据失败: " . $e->getMessage());
        }
    }
}
